package com.hfzy.ihk.web.linkcall.biz.flow.config;

import com.hfzy.ihk.common.core.elasticsearch.EsQueryUtils;
import com.hfzy.ihk.common.core.elasticsearch.service.EsBaseServiceImpl;
import com.hfzy.ihk.common.util.Utils;
import com.hfzy.ihk.common.util.string.StringUtil;
import com.hfzy.ihk.common.web.WebResult;
import com.hfzy.ihk.facade.linkcall.entity.flow.config.SpeakingFlowStep;
import com.hfzy.ihk.web.linkcall.dao.SpeakingFlowStepRepository;
import com.hfzy.ihk.web.linkcall.support.annotation.PreProcessParam;
import com.hfzy.ihk.web.linkcall.support.annotation.PushMsgToAIService;
import com.hfzy.ihk.web.linkcall.utils.UserUtils;
import com.hfzy.ihk.web.linkcall.utils.WebResultUtils;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import java.util.*;

@Component
public class SpeakingFlowStepBiz extends EsBaseServiceImpl<SpeakingFlowStep> {
    @Autowired
    SpeakingFlowStepRepository speakingFlowStepRepository;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Override
    protected ElasticsearchCrudRepository getReposity() {
        return speakingFlowStepRepository;
    }


    @PushMsgToAIService
    public WebResult addSpeakingFlowStep(SpeakingFlowStep speakingFlowStep){
        WebResult webResult = null;
        speakingFlowStep.setCreateTime(new Date());
        speakingFlowStep.setModTime(new Date());
        speakingFlowStep.setCreateUserId(UserUtils.getCurrentUserId()!=null?UserUtils.getCurrentUserId():0l);
        if(Utils.isNullString(speakingFlowStep.getId())){
            speakingFlowStep.setId(UUIDs.base64UUID());
        }
        speakingFlowStepRepository.save(speakingFlowStep);
        webResult = WebResultUtils.getSuccessCharWebResult("",0,null);
        return webResult;
    }

    @PreProcessParam
    public Page<SpeakingFlowStep> getSpeakingFlowStepByPage(Map<String,String> params){
        BoolQueryBuilder boolQueryBuilder = getQueryBuilderByParams(params);
        int pageNum = Integer.valueOf(params.get("page"))-1;
        int pageSize = Integer.valueOf(params.get("pageSize"));
        //添加排序字段
        FieldSortBuilder fieldSortBuilder = null;
        if(params.containsKey("orderByModeTime")){
            fieldSortBuilder = SortBuilders.fieldSort("modTime").order(SortOrder.DESC);
        }else{
            fieldSortBuilder = SortBuilders.fieldSort("createTime").order(SortOrder.DESC);
        }
        return getSpeakingFlowStepPageByCondition(pageNum,pageSize,boolQueryBuilder,fieldSortBuilder);
    }

    @PreProcessParam
    public List<SpeakingFlowStep> getSpeakingFlowStepList(Map<String,String> params){
        List<SpeakingFlowStep> speakingFlowStepList = null;
        BoolQueryBuilder boolQueryBuilder = getQueryBuilderByParams(params);
        Iterator<SpeakingFlowStep> iterator = speakingFlowStepRepository.search(boolQueryBuilder).iterator();
        if (iterator != null) {
            speakingFlowStepList = new ArrayList<SpeakingFlowStep>();
            while (iterator.hasNext()) {
                SpeakingFlowStep next = iterator.next();
                speakingFlowStepList.add(next);
            }
        }
        return speakingFlowStepList;
    }


    public SpeakingFlowStep getSpeakingFlowStepById(String id){
        Map params = new HashMap();
        params.put("id",id);
        List<SpeakingFlowStep> speakingFlowStepList = getSpeakingFlowStepList(params);
        return Utils.getFirst(speakingFlowStepList);
    }

    public List<SpeakingFlowStep> getSpeakingFlowStepByFlowId(String flowId){
        Map params = new HashMap();
        params.put("flowId",flowId);
        return getSpeakingFlowStepList(params);
    }


    public BoolQueryBuilder getQueryBuilderByParams(Map<String,String> params){
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        Iterator entries = params.entrySet().iterator();
        while (entries.hasNext()){
            Map.Entry entry = (Map.Entry) entries.next();
            String key = entry.getKey().toString();
            switch (key){
                case "createUserId":
                    boolQueryBuilder.must(EsQueryUtils.termQuery("createUserId",params.get("createUserId")));
                    break;
                case "createTimeStart":
                    boolQueryBuilder.must(EsQueryUtils.rangeQuery("createTime", params.get("createTimeStart"),
                            null, true, false));
                break;
                case "createTimeEnd" :
                    boolQueryBuilder.must(EsQueryUtils.rangeQuery("createTime", null,
                            params.get("createTimeEnd"), false, true));
                    break;
                case "stepName":
                    QueryBuilder projectName = EsQueryUtils.wildcardQuery("stepName", "*"+params.get("stepName")+"*");
                    EsQueryUtils.boolQuery(boolQueryBuilder, EsQueryUtils.BoolType.MUST, projectName);
                    break;
                case "id":
                    QueryBuilder queryBuilder = EsQueryUtils.termQuery("id",params.get("id"));
                    boolQueryBuilder.must(queryBuilder);
                    break;
                case "flowId":
                    boolQueryBuilder.must(EsQueryUtils.termQuery("flowId",params.get("flowId")));
                    break;
                case "packageId":
                    boolQueryBuilder.must(EsQueryUtils.termQuery("packageId",params.get("packageId")));
                    break;
                case "contentNoEmpty":
                    boolQueryBuilder.must(QueryBuilders.existsQuery("content"));
                    boolQueryBuilder.must(QueryBuilders.rangeQuery("content").gt(1));//长度大于1 ，为空的或者不存在的则过滤
                    break;
                case "firstStepByFlow":
                    boolQueryBuilder.must(EsQueryUtils.termQuery("firstStepByFlow",Boolean.parseBoolean(params.get("firstStepByFlow"))));
                    break;
                default:
                    break;
            }
        }
        return boolQueryBuilder;
    }

    public Page<SpeakingFlowStep> getSpeakingFlowStepPageByCondition(int pageNum,int pageSize,BoolQueryBuilder boolQueryBuilder,FieldSortBuilder fieldSortBuilder){
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder).withSort(fieldSortBuilder).withPageable(PageRequest.of(pageNum,pageSize));
        return speakingFlowStepRepository.search(builder.build());
    }

    @PushMsgToAIService
    public WebResult saveSpeakingFlowStep(SpeakingFlowStep speakingFlowStep){
        WebResult webResult = null;
        if(!Utils.isNullString(speakingFlowStep.getId())){
            if(speakingFlowStep.getCreateTime()==null){
                speakingFlowStep.setCreateTime(new Date());
            }
            speakingFlowStep.setModTime(new Date());
            update(speakingFlowStep);
        }else{
            webResult = WebResultUtils.getFailCharWebResult("参数异常");
        }
        webResult = WebResultUtils.getSuccessCharWebResult("",0,null);
        return webResult;
    }

    @PushMsgToAIService
    public WebResult deleteSpeakingFlowStepById(String id){
        WebResult webResult = null;
        boolean flag = deleteById(id);
        if(flag){
            webResult = WebResultUtils.getSuccessCharWebResult("",0,null);
        }else{
            webResult = WebResultUtils.getFailCharWebResult("参数异常");
        }
        return  webResult;
    }

    @PushMsgToAIService
    public boolean addSpeakingFlowStepList(List<SpeakingFlowStep> speakingFlowSteps){
        speakingFlowSteps.forEach(it->{
            it.setCreateUserId(UserUtils.getCurrentUserId()!=null?UserUtils.getCurrentUserId():0l);
        });
        this.speakingFlowStepRepository.saveAll(speakingFlowSteps);
        return true;
    }

    @PushMsgToAIService
    public boolean updateSpeakingFlowStepList(List<SpeakingFlowStep> speakingFlowSteps){
        boolean flag = true;
        for(SpeakingFlowStep speakingFlowStep:speakingFlowSteps){
            speakingFlowStep.setCreateUserId(UserUtils.getCurrentUserId()!=null?UserUtils.getCurrentUserId():0l);
            flag = this.speakingFlowStepRepository.updateSomeFieldsOnlyNotNull(speakingFlowStep);
            if(!flag)
                break;
        }
        return flag;
    }

    public List<SpeakingFlowStep> getDefalutSpeakingFlowSteps(){
        Map params = new HashMap();
        params.put("packageId","null");
        params.put("flowId","null");
        return getSpeakingFlowStepList(params);
    }
}
